import { defineStore } from 'pinia'
import { getNoopActions, injectState, useRemote, useWorker, wrapSafeActions } from '@/controller/base/index'
import type { Worker } from '@/controller/base/types/worker'
import type { Remote } from '@/controller/base/types/remote'
import type { DishwasherController } from '../Dishwasher/definition'
import { DishwasherActions, DishwasherGetters, createDishwasherState } from '../Dishwasher/index'
import { DemoBaseActions, createDemoBaseState, setDemoBaseState } from './BaseAppliance'
import { merge } from 'lodash'
import { getDemoProgramActions, getDemoProgramGetters } from './common/Program'
import type { DemoDatasource } from '@/demo/types'
import { useProgramEffects } from '../common/Program/program'
import type { ProgramController } from '../common/Program/definition'

let demoDatasource!: DemoDatasource

export function useDemoDishwasherControl(): DishwasherController.Control {
  const createDemoDishwasherState: () => DishwasherController.State = () =>
    injectState(
      () => merge(createDishwasherState(), createDemoBaseState()),
      (state) => {
        setDemoBaseState(state, demoDatasource)
      }
    )
  const DemoDishwasherGetters: DishwasherController.Getters = {
    ...(getDemoProgramGetters(DishwasherGetters as ProgramController.Getters) as DishwasherController.Getters),
    // Demo模式 不使用程序分组功能
    programGroupsConfig: () => null,
  }
  const DemoDishwasherActions: DishwasherController.Actions = wrapSafeActions<
    DishwasherController.Store,
    DishwasherController.Actions
  >({
    ...merge(getNoopActions(DishwasherActions), DemoBaseActions),
    ...getDemoProgramActions(demoDatasource),
    customDisplayOptionFormatter: DishwasherActions.customDisplayOptionFormatter,
  })
  const useDemoStore = defineStore<
    'DemoDishwasher',
    DishwasherController.State,
    DishwasherController.Getters,
    DishwasherController.Actions
  >('DemoDishwasher', {
    state: createDemoDishwasherState,
    getters: DemoDishwasherGetters,
    actions: DemoDishwasherActions,
  })

  const store = useDemoStore() as DishwasherController.Store
  const worker = useWorker(store) as Worker.ApplianceWorker<DishwasherController.Store>
  const remote = useRemote(store) as Remote.ApplianceRemote<DishwasherController.Store>
  return { store, worker, remote }
}

export function createDemoDishwasherControl(datasource: DemoDatasource): DishwasherController.Control {
  demoDatasource = datasource
  const control = useDemoDishwasherControl()
  useProgramEffects(control)
  return control
}
